package com.lcu.wl.modules.tools.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.lcu.wl.common.utils.*;
import com.lcu.wl.modules.tools.entity.QuartzJob;
import com.lcu.wl.modules.tools.mapper.QuartzJobMapper;
import com.lcu.wl.modules.tools.service.IQuartzJobService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.lcu.wl.modules.tools.utils.ScheduleUtils;
import org.quartz.CronTrigger;
import org.quartz.Scheduler;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.PostConstruct;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.*;

/**
 * <p>
 * 定时任务 服务实现类
 * </p>
 *
 * @author wanglei
 * @since 2021-03-15
 */
@Service("quartzJobService")
public class QuartzJobServiceImpl extends ServiceImpl<QuartzJobMapper, QuartzJob> implements IQuartzJobService {

    @Autowired
    private Scheduler scheduler;

    /**
     *项目初始化时，初始化定时器
     */
    @PostConstruct
    public void init(){
        List<QuartzJob> quartzJobList = this.list();
        for (QuartzJob quartzJob : quartzJobList){
            CronTrigger cronTrigger = ScheduleUtils.getCronTrigger(scheduler, quartzJob.getJobId());
            //如果不存在，则创建
            if (cronTrigger == null){
                ScheduleUtils.createScheduleJob(scheduler,quartzJob);
            }else {
                ScheduleUtils.updateScheduleJob(scheduler,quartzJob);
            }
        }
    }

    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        String taskName = (String) params.get("taskName");
        String createTime = (String) params.get("createTime");
        String endTime = (String) params.get("endTime");

        QueryWrapper<QuartzJob> queryWrapper = new QueryWrapper<>();

        if (StringUtils.isNotBlank(createTime) && StringUtils.isNotBlank(endTime)){
            queryWrapper.between("create_time",createTime,endTime);
        }

        IPage<QuartzJob> page = this.page(new Query<QuartzJob>().getPage(params),
                queryWrapper.like(StringUtils.isNotBlank(taskName),"bean_name", taskName)
        );

        return new PageUtils(page);
    }

    @Override
    public List<QuartzJob> queryAll(Map<String, Object> params) {
        String taskName = (String) params.get("taskName");
        String createTime = (String) params.get("createTime");
        String endTime = (String) params.get("endTime");

        QueryWrapper<QuartzJob> queryWrapper = new QueryWrapper<>();

        if (StringUtils.isNotBlank(createTime) && StringUtils.isNotBlank(endTime)){
            queryWrapper.between("create_time",createTime,endTime);
        }

        List<QuartzJob> quartzJobs = this.list(queryWrapper.like(StringUtils.isNotBlank(taskName),"bean_name",taskName));

        return quartzJobs;
    }

    @Override
    public void download(List<QuartzJob> quartzJobs, HttpServletResponse response) throws IOException {
        List<Map<String, Object>> list = new ArrayList<>();
        for (QuartzJob quartzJob : quartzJobs) {
            Map<String,Object> map = new LinkedHashMap<>();

            map.put("Bean名称", quartzJob.getBeanName());
            map.put("参数", quartzJob.getParams());
            map.put("表达式", quartzJob.getCronExpression());
            map.put("状态", quartzJob.getStatus() == 1 ? "暂停中" : "运行中");
            map.put("描述", quartzJob.getRemark());
            map.put("创建日期", quartzJob.getCreateTime());
            list.add(map);
        }
        FileUtil.downloadExcel(list, response);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void saveJob(QuartzJob quartzJob) {
        quartzJob.setCreateTime(new Date());
        quartzJob.setStatus(Constant.ScheduleStatus.NORMAL.getValue());
        this.save(quartzJob);

        ScheduleUtils.createScheduleJob(scheduler, quartzJob);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void update(QuartzJob quartzJob) {
        ScheduleUtils.updateScheduleJob(scheduler, quartzJob);
        this.updateById(quartzJob);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteBatch(Long[] jobIds) {
        for(Long jobId : jobIds){
            ScheduleUtils.deleteScheduleJob(scheduler, jobId);
        }
        //删除数据
        this.removeByIds(Arrays.asList(jobIds));
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void run(Long jobId) {
        ScheduleUtils.run(scheduler, this.getById(jobId));
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void pause(Long jobId) {
        ScheduleUtils.pauseJob(scheduler, jobId);
        updateStatus(jobId, Constant.ScheduleStatus.PAUSE.getValue());
    }

    @Override
    public int updateStatus(Long jobId, int status) {
        Map<String, Object> map = new HashMap<>(2);
        map.put("jobId", jobId);
        map.put("status", status);
        return baseMapper.updateStatus(map);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void resume(Long jobId) {
        ScheduleUtils.resumeJob(scheduler, jobId);
        updateStatus(jobId, Constant.ScheduleStatus.NORMAL.getValue());
    }
}
